package com.jnu.erp.framework.config;

import io.minio.*;
import io.minio.errors.*;
import io.minio.http.Method;
import io.minio.messages.Bucket;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

@Component
@Slf4j
public class MinIOComponent {
    @Autowired
    private MinioConfig minioConfig;

    @Autowired
    private MinioClient minioClient;

    /**
     * 文件上传
     * @param file
     * @return
     */
    public String uploadFile(String path, MultipartFile file) {
        //获取相关配置
        String bucketname = minioConfig.getBucketname();

        //获取原生文件名 xxx.jpg
        String originalFilename = file.getOriginalFilename();

        //JDK8的日期格式化
        LocalDateTime localDateTime = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd");

        //拼装路径，上存储的路径 2021/2/14/xxxx.jpg
        //2021/2/5/
        String folder = formatter.format(localDateTime);
        // 生成文件上传唯一名称
        String filename = UUID.randomUUID().toString().replaceAll("-", "");
        //.jpg
        String extension = originalFilename.substring(originalFilename.lastIndexOf("."));
        //新文件名
        String newFilename =  path + "/" + folder + "/" + filename + extension;

        try {
            return uploadFile(file.getInputStream(), bucketname, file.getContentType(), newFilename);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public String uploadFile(InputStream stream, String bucket, String contentType, String objectKey) {
        // TODO Auto-generated method stub
        // 文件流上传
        try {
            ObjectWriteResponse putObject = minioClient.putObject(PutObjectArgs.builder().bucket(bucket).object(objectKey).stream(stream, stream.available(), -1).contentType(contentType).build());
            // 返回文件上传的唯一标识
            //return objectKey;
            if (putObject != null) {
                //String imgUrl = minioClient.getObjectUrl(bucketname,newFileName);
                String imgUrl = minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder().method(Method.GET).bucket(bucket).object(objectKey).build());
                return imgUrl;
            }
        } catch (InvalidKeyException | ErrorResponseException | InsufficientDataException | InternalException
                 | InvalidResponseException | NoSuchAlgorithmException | ServerException | XmlParserException
                 | IllegalArgumentException | IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            log.error("文件上传失败: {}", e.getMessage(), e);
        }
        return null;
    }

    public boolean removeFile(String objectKey, String bucket) {
        // TODO Auto-generated method stub
        try {
            minioClient.removeObject(RemoveObjectArgs.builder().bucket(bucket).object(objectKey).build());
            return true;
        } catch (InvalidKeyException | ErrorResponseException | InsufficientDataException | InternalException
                 | InvalidResponseException | NoSuchAlgorithmException | ServerException | XmlParserException
                 | IllegalArgumentException | IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            log.error("error: {}", e.getMessage(), e);
        }
        return false;
    }

    public GetObjectResponse downloadFile(String objectKey, String bucket) {
        // TODO Auto-generated method stub
        try {
            // 返回文件流
            GetObjectResponse response = minioClient.getObject(GetObjectArgs.builder().bucket(bucket).object(objectKey).build());
            System.out.print("Headers:--------"+ response.headers().toString());
            return response;
        } catch (InvalidKeyException | ErrorResponseException | InsufficientDataException | InternalException
                 | InvalidResponseException | NoSuchAlgorithmException | ServerException | XmlParserException
                 | IllegalArgumentException | IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            log.error("error: {}", e.getMessage(), e);
        }
        return null;
    }

    /**
     * 生成上传图片预览地址
     * @param objectKey
     * @param bucket
     * @return
     * @throws InvalidKeyException
     * @throws ErrorResponseException
     * @throws InsufficientDataException
     * @throws InternalException
     * @throws InvalidResponseException
     * @throws NoSuchAlgorithmException
     * @throws XmlParserException
     * @throws ServerException
     * @throws IllegalArgumentException
     * @throws IOException
     */
    public String getPreviewAddress(String objectKey, String bucket) throws InvalidKeyException, ErrorResponseException, InsufficientDataException, InternalException, InvalidResponseException, NoSuchAlgorithmException, XmlParserException, ServerException, IllegalArgumentException, IOException{
        return minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder().method(Method.GET).bucket(bucket).object(objectKey).build());
    }

    public List<String> getBucketName(){
        List<String> list = new ArrayList<String>();
        List<Bucket> buckets = null;
        try {
            buckets = this.minioClient.listBuckets();
        } catch (InvalidKeyException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ErrorResponseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InsufficientDataException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InternalException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvalidResponseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ServerException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (XmlParserException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        for (Bucket bucket : buckets) {
            System.out.println(bucket.creationDate() + ", " + bucket.name());
            list.add(bucket.name());
        }
        return list;
    }

    public boolean createBucket(String bucket) {
        // TODO Auto-generated method stub
        boolean target = false;
        // 判断桶是否存在
        BucketExistsArgs exist = BucketExistsArgs.builder().bucket(bucket).build();

        try {
            boolean result = minioClient.bucketExists(exist);
            if(!result){
                MakeBucketArgs create =MakeBucketArgs.builder().bucket(bucket).build();
                minioClient.makeBucket(create);
                target = true;
            }

        } catch (InvalidKeyException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            log.error("error: {}", e.getMessage(), e);
        } catch (ErrorResponseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            log.error("error: {}", e.getMessage(), e);
        } catch (InsufficientDataException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            log.error("error: {}", e.getMessage(), e);
        } catch (InternalException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            log.error("error: {}", e.getMessage(), e);
        } catch (InvalidResponseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            log.error("error: {}", e.getMessage(), e);
        } catch (NoSuchAlgorithmException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            log.error("error: {}", e.getMessage(), e);
        } catch (ServerException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            log.error("error: {}", e.getMessage(), e);
        } catch (XmlParserException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            log.error("error: {}", e.getMessage(), e);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            log.error("error: {}", e.getMessage(), e);
        }

        return target;
    }

    public boolean removeBucket(String bucket) {
        // TODO Auto-generated method stub
        // 判断桶是否存在
        BucketExistsArgs exist = BucketExistsArgs.builder().bucket(bucket).build();
        try {
            boolean result = minioClient.bucketExists(exist);
            if(result){
                minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucket).build());
                return true;
            }
        } catch (InvalidKeyException | ErrorResponseException | InsufficientDataException | InternalException
                 | InvalidResponseException | NoSuchAlgorithmException | ServerException | XmlParserException
                 | IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            log.error("error: {}", e.getMessage(), e);
        }
        return false;
    }

//    public boolean setBucketPolicy(String bucket, String policy) {
//        // TODO Auto-generated method stub
//        // 判断桶是否存在
//        BucketExistsArgs exist = BucketExistsArgs.builder().bucket(bucket).build();
//
//        try {
//            boolean result = this.minioClient.bucketExists(exist);
//            if(result){
//                BucketPolicyInterface bucketPolicy = BuckerPolicyFactory.getBucketPolicyInterface(policy);
//                return bucketPolicy.createBucketPolicy(this.minioClient, bucket);
//            }
//        } catch (InvalidKeyException | ErrorResponseException | InsufficientDataException | InternalException
//                 | InvalidResponseException | NoSuchAlgorithmException | ServerException | XmlParserException
//                 | IOException e) {
//            // TODO Auto-generated catch block
//            log.error("error: {}", e.getMessage(), e);
//        }
//        return false;
//    }

}
